#include"DirectXFramework.h"

//Initialize DirectX//
void CDirectXFramework::InitDX(HWND& hWnd, HINSTANCE& hInst, bool bWindowed)
{
	//Copy Window Handle//
	m_hWnd = hWnd;
	//Error Check Copy//
	if(m_hWnd == NULL)
	{
		checkpoint = ::MessageBoxA(NULL, "Failed to Copy Window Handler", "hWnd Failed", MB_OK | MB_ICONERROR); 
		::PostQuitMessage(0);
		return;
	}	

	//Create the D3D Object//
	m_pD3DObject = Direct3DCreate9(D3D_SDK_VERSION);
	if(m_pD3DObject == NULL)
	{::MessageBoxA(m_hWnd, "Failed to Create the Direct3D Object", "D3D9 Failed", MB_OK | MB_ICONERROR);}

	//Set D3D Device Presentation Parameters Before Creating Device//
	D3DPRESENT_PARAMETERS D3Dpp;
	ZeroMemory(&D3Dpp, sizeof(D3Dpp));  //NULL the structure's memory//

	D3Dpp.hDeviceWindow					= hWnd;										//Handle to the focus window//
	D3Dpp.Windowed						= bWindowed;								//Windowed or Full-screen boolean//
	D3Dpp.AutoDepthStencilFormat		= D3DFMT_D24S8;								//Format of depth/stencil buffer, 24 bit depth, 8 bit stencil//
	D3Dpp.EnableAutoDepthStencil		= TRUE;										//Enables Z-Buffer (Depth Buffer)//
	D3Dpp.BackBufferCount				= 1;										//Change if need of > 1 is required at a later date//
	D3Dpp.BackBufferFormat				= D3DFMT_X8R8G8B8;							//Back-buffer format, 8 bits for each pixel//
	D3Dpp.BackBufferHeight				= SCREEN_HEIGHT;									//Make sure resolution is supported, use adapter modes//
	D3Dpp.BackBufferWidth				= SCREEN_WIDTH;									//(Same as above)//
	D3Dpp.SwapEffect					= D3DSWAPEFFECT_DISCARD;					//Discard back-buffer, must stay discard to support multi-sample//
	D3Dpp.PresentationInterval			= m_bVsync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_ONE; //Present back-buffer immediately (D3DPRESENT_INTERVAL_IMMEDIATE),
	//unless V-Sync is on, but I am using D3DPRESENT_INTERVAL_ONE,
	//which updates with the screen refresh//
	D3Dpp.Flags							= D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;		//This flag should improve performance, if not set to NULL.//
	D3Dpp.FullScreen_RefreshRateInHz	= bWindowed ? 0 : D3DPRESENT_RATE_DEFAULT;	//Full-screen refresh rate, use adapter modes or default//
	D3Dpp.MultiSampleQuality			= 0;										//MSAA currently off//
	D3Dpp.MultiSampleType				= D3DMULTISAMPLE_NONE;						//MSAA currently off//

	//Check Device Capabilities//
	DWORD deviceBehaviorFlags = 0;
	checkpoint = m_pD3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_D3DCaps);
	if(checkpoint != S_OK)
	{::MessageBoxA(m_hWnd, "Failed to Get Device Capabilites", "GetDeviceCaps() Failed", MB_OK | MB_ICONERROR);}

	//Determine vertex processing mode//
	if(m_D3DCaps.DevCaps & D3DCREATE_HARDWARE_VERTEXPROCESSING)
	{
		//if Hardware vertex processing supported (video card)//
		deviceBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;	
	}
	else
	{
		//else, use software (CPU)//
		deviceBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; 
	}

	//If hardware vertex processing is on, check pure device support//
	if(m_D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE && deviceBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
	{
		deviceBehaviorFlags |= D3DCREATE_PUREDEVICE;	
	}

	//Create the D3D Device with the present parameters and device flags above//
	checkpoint = m_pD3DObject->CreateDevice(
		D3DADAPTER_DEFAULT,		//which adapter to use, set to primary//
		D3DDEVTYPE_HAL,			//device type to use, set to hardware rasterization//
		hWnd,					//handle to the focus window//
		deviceBehaviorFlags,	//behavior flags//
		&D3Dpp,					//presentation parameters//
		&m_pD3DDevice);			//returned device pointer//
	if(checkpoint != S_OK)
	{::MessageBoxA(m_hWnd, "Failed to Create Device", "CreateDevice() Failed", MB_OK | MB_ICONERROR);}

	//Initialize the Frames Per Second Counter//
	InitFPS();

	//Initialize DirectInput//
	//Create the DI Object//
	DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_pDIObject, NULL);
	//Initialize Mouse//
	m_pDIObject->CreateDevice(GUID_SysMouse, &m_pDIMouse, NULL);
	//Set up Mouse (c_dfDIMouse2 = 8 button mouse)//
	m_pDIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	m_pDIMouse->SetDataFormat(&c_dfDIMouse2);


	// Initialize Keyboard
	m_pDIObject->CreateDevice(GUID_SysKeyboard, &m_pDIKeyboard, NULL);
	// Set up Keyboard
	m_pDIKeyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	m_pDIKeyboard->SetDataFormat(&c_dfDIKeyboard);

	//Create the Font Object//
	m_NumFonts = AddFontResourceEx(L"Misc/QuartzMS.ttf", FR_PRIVATE, 0);
	//Check the Font Object//
	if(m_NumFonts <=0)
	{::MessageBoxA(m_hWnd, "Failed to Add a Font Resource", "AddFontResource Failed", MB_OK | MB_ICONERROR);}

	//Load D3DXFont//
	checkpoint = D3DXCreateFont(m_pD3DDevice, 25, 0, FW_BOLD, 0, false, DEFAULT_CHARSET, 
		OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Misc/Quartz MS"), &m_pD3DFont);
	//Check if the Font was Created//
	if(checkpoint != S_OK)
	{::MessageBoxA(m_hWnd, "D3DXCreateFont has failed", "Font Failed", MB_OK | MB_ICONERROR);}


	checkpoint = D3DXCreateFont(m_pD3DDevice, 150, 0, FW_BOLD, 0, false, DEFAULT_CHARSET, 
		OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Misc/Quartz MS"), &m_pD3DFontBig);
	//Check if the Font was Created//
	if(checkpoint != S_OK)
	{::MessageBoxA(m_hWnd, "D3DXCreateFont has failed", "Font Failed", MB_OK | MB_ICONERROR);}



	//Create a Single Sprite Object//
	checkpoint = D3DXCreateSprite(m_pD3DDevice, &m_pD3DSprite);
	//Check the Sprite Obejct//
	if(checkpoint != S_OK)
	{::MessageBoxA(m_hWnd, "Failed to Create the Sprite Object", "D3DXCreateSprite Failed", MB_OK | MB_ICONERROR);}

	// Seed rand() with time
	srand(timeGetTime());

	m_Menu.InitMenu(m_pD3DDevice);
	m_Board.InitBoard(m_pD3DDevice);

	//Jordon, this shouldn't be in the for loop anymore because we do not need to initialize the//
	//mesh and textures for every player since they are all stored at 1 location (which would be//
	//in the deck), so I moved it outside of the for loop below									//
	m_Deck.InitCard(m_pD3DDevice);

	for(int player = 0; player < NumberOfPlayers; player++)
	{
		m_Hand[player].ToggleVisible();
	}
	
	m_Deck.Reset();

	for (int a=0; a < 4; a++)
	{
		for (int i=0; i < 5; i++)
			m_Hand[a].SetCard(i, m_Deck.GetValue());
	}

	redraw = true;

	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

	///gary 
	m_PlayerController.InitController(m_pD3DDevice);
	
	//gary code
	//sets up the players pawns on start pos 
	for(int player = 0; player < NumberOfPlayers; player++)
	{
		//this is used to hold player start pos
		D3DXVECTOR3  temp;
		temp = m_Board.GetStartLoc(player);
		//pass players start pos to set pawns based on that pos
		setPawnsOnStart(player,temp);
	}
	
	//gary code
	//sets up our billboard mesh stuff
	//verts, textures,init number boards on home and start 
	init_posterObjects();

	m_Players[0].SetStartTileNumber(0);
	m_Players[1].SetStartTileNumber(15);
	m_Players[2].SetStartTileNumber(30);
	m_Players[3].SetStartTileNumber(45);


	//gary code
	//this sets up the color range array for the menu
	m_range[0] = D3DCOLOR_ARGB(255, 255, 0, 0);
	m_range[1] =D3DCOLOR_ARGB(255, 255, 255, 0);
	m_range[2] = D3DCOLOR_ARGB(255, 0, 0, 255);
	m_range[3] = D3DCOLOR_ARGB(255, 205, 0, 205);


	//gary code 
	//this sets up and inits the FMOD sound engine
	m_soundEng.initSoundEngine(m_hWnd);
}